# pylint: disable=wildcard-import,unused-wildcard-import,trailing-whitespace
# pylint: disable=consider-using-f-string,no-value-for-parameter,invalid-name
import numpy as np
import taichi as ti
from .gtaichi import *

@ti.func
def point_light(light:Light,ints:Intersection):
    """
    点光源
    返回 p发光位置,le辐射强度和
    """
    le = ti.Vector([0.,0.,0.])
    p = ti.Vector([0.,0.,0.])
    op = light.p-ints.p
    sq = 0.
    if ti.math.dot(ints.n,op)>0:
        op2 = op*op
        sq = op2.x+op2.y+op2.z
        p = light.p
        le = light.color * light.power/(sq*light.pdf_v)
    return p,le,sq

SKY_SPHERE_RADIUS = 1e3
SKY_SPHERE_RADIUS_SQR = 1e6
SKY_POWER_SCALE = 2e2
@ti.func
def sky_light(light:Light,ints:Intersection,bounding):
    """
    天空
    返回 p发光位置,le辐射强度和
    """
    sq = 0.
    le = ti.Vector([0.,0.,0.])
    xi = random_vec2()
    phi = 2*np.pi*xi.x
    theta = .5*np.pi*xi.y
    theta_sin = ti.math.sin(theta)
    p = ti.Vector([
        SKY_SPHERE_RADIUS*theta_sin * ti.math.sin(phi),
        SKY_SPHERE_RADIUS*theta_sin * ti.math.cos(phi),
        SKY_SPHERE_RADIUS*ti.math.cos(theta)
    ])
    p += light.p
    op = p-ints.p
    if ti.math.dot(ints.n,op)>0:
        op2 = op*op
        sq = op2.x+op2.y+op2.z
        if light.tex>=0:
            le = bounding.get_sphere_tex(p,light.offset,light.tex)
            le *= 2.*np.pi*SKY_POWER_SCALE*light.color*light.power/(sq*light.pdf_v)
        else:
            le =  2.*np.pi*SKY_POWER_SCALE*light.color*light.power/(sq*light.pdf_v)
    return p,le,sq

@ti.func
def direct_light(light:Light,ints:Intersection):
    """
    方向光 ,灯的位置仅仅提供一个到原点的距离参数
    """
    sq = 0.
    le = ti.Vector([0.,0.,0.])
    p = ti.Vector([0.,0.,0.])
    op = light.p
    if ti.math.dot(ints.n,-light.dir)>0:
        op2 = op * op
        sq = op2.x+op2.y+op2.z
        le = light.color * light.power/(sq*light.pdf_v)
        sq = 1e12
        p = ints.p + 1e6*(-light.dir)
    return p,le,sq

@ti.func
def area_light(light:Light,ints:Intersection,bounding):
    """
    区域灯,仅支持球和矩形
    """
    sq = 0.
    le = ti.Vector([0.,0.,0.])
    p = ti.Vector([0.,0.,0.])
    if light.count==0: #球
        sphere = bounding.sphere[light.offset]
        xi = random_vec2()
        phi = 2*np.pi*xi.x
        theta = .5*np.pi*xi.y
        theta_sin = ti.math.sin(theta)
        p = ti.Vector([
            sphere.radius*theta_sin * ti.math.sin(phi),
            sphere.radius*theta_sin * ti.math.cos(phi),
            sphere.radius*ti.math.cos(theta)
        ])
        p += sphere.center
        op = ints.p-p
        op2 = op * op
        sq = op2.x+op2.y+op2.z
        le = light.color*light.power/(sq*light.pdf_v)
    elif light.count==2: #矩形
        trangle = bounding.trangle[light.offset]
        xi = random_vec2()
        ab = trangle.b-trangle.a
        ac = trangle.c-trangle.a
        p = ab*xi.x+ac*xi.y+trangle.a
        op = ints.p-p
        op2 = op * op
        sq = op2.x+op2.y+op2.z
        #sin = ti.math.sqrt(1.-ti.math.dot(ab,ac))
        #a = sin*ti.math.distance(trangle.c,trangle.a)*ti.math.distance(trangle.b,trangle.a)
        le = light.color*light.power/(sq*light.pdf_v)

    return p,le,sq
